package com.hc.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class TokenFilter extends ZuulFilter {

    @Override
    public Object run() throws ZuulException {
        // 获取上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //从请求头里获取token对象
        String userToken = request.getHeader("userToken");
        //从请求参数里获取token对象
        if(StringUtils.isBlank((userToken))){
            userToken = request.getParameter("userToken");
        }
        //登录校验逻辑 根据公司情况自定义
        if (StringUtils.isEmpty(userToken)) {
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(401);
            currentContext.setResponseBody("userToken is null");
            return null;
        }
    // 否则正常执行业务逻辑.....
        return null;
    }
    // 过滤器类型
    @Override
    public String filterType() {
// 1）pre 可以在请求被路由之前调用。适用于身份认证的场景，认证通过后再继续执行下面的流程。
// 2）post 在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头，记录响应日志等应用场景。
// 3）route 在路由请求时被调用。适用于灰度发布场景，在将要路由的时候可以做一些自定义的逻辑。
// 4）error 处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器，可以用来统一记录错误信息。
        return "pre";
    }
    @Override
    public boolean shouldFilter() {
// 是否执行该过滤器，true 为执行，false 为不执行，这个也可以利用配置中心来实现，达到动态的开启和关闭过滤器。
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        if ("/haochen/member/login".equalsIgnoreCase(request.getRequestURI())){
            return false;
        }
        return true;
    }
    // 过滤器的执行顺序，数值越小，优先级越高。
    @Override
    public int filterOrder() {
// 过滤器的执行顺序，数值越小，优先级越高。
        return 0;
    }
}
